#pragma once
#include <signal.h>

#include "Connect.hpp"
#include "ThreadPool.hpp"

#define PORT 8080

class Acceptor
{
private:
    Socket _listenSocket; // 监听套接字
    EventLoop *_lsLoop;   // 监听套接字事件回调管理
    Channel *_lsChannel;  // 监听套接字事件监控管理

    using AcceptCallback = std::function<void(int)>;
    AcceptCallback _acceptCallback; // 接收到新连接回调

    // 创建监听套接字
    int CreatListenFd(uint64_t port)
    {
        bool ret = _listenSocket.CreateServer(port);
        if (!ret)
            ELOG("CREATE LISTENFD FAILED!");
        return _listenSocket.Fd();
    }

    // accept到一个新连接调用
    void HandleRead()
    {
        int newFd = _listenSocket.Accept();
        if (newFd < 0)
            return;

        if (_acceptCallback)
            _acceptCallback(newFd);
    }

public:
    Acceptor(EventLoop *Loop, uint64_t port = PORT) : _lsLoop(Loop),
                                                      _listenSocket(CreatListenFd(port)),
                                                      _lsChannel(new Channel(Loop, _listenSocket.Fd()))
    {
        _lsChannel->SetReadCallback(std::bind(&Acceptor::HandleRead, this));
    }

    // 设定获取连接回调
    void SetAcceptCallback(const AcceptCallback &cd) { _acceptCallback = cd; }

    // 启动监听（开始接收接收）
    void Listen()
    {
        _lsChannel->EnableRead();
    }
};

class TcpServer
{
private:
    uint64_t _nextId;                                   // 用于维护连接/任务id的自增
    int _port;                                           // 服务端开放端口号
    int _timeout;                                       // 用于记录连接的生命周期的时间
    bool _enableInactiveRelease;                        // 是否开启连接非活跃释放（生命周期）
    EventLoop _baseloop;                                // 这是主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;                                 // 这是监听套接字的管理对象
    LoopThreadPool _threadPool;                         // 线程池
    std::unordered_map<uint64_t, PtrConnection> _conns; // 保存管理所有连接对应的shared_ptr对象

    // 用于设定连接的回调函数

    using ConnectedCallback = std::function<void(const PtrConnection &)>;
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>;
    using ClosedCallback = std::function<void(const PtrConnection &)>;
    using AnyEventCallback = std::function<void(const PtrConnection &)>;
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback; // 连接成功的回调
    MessageCallback _message_callback;     // 消息到达的回调
    ClosedCallback _closed_callback;       // 连接关闭的回调
    AnyEventCallback _event_callback;      // 任意事件的回调

private:
    // 添加定时任务inloop
    void RunAfterInLoop(const Functor &task, int delay)
    {
        _nextId++;
        _baseloop.TimerAdd(_nextId, delay, task);
    }

    // 新连接的管理（设定连接属性）
    void NewConnection(int newFd)
    {
        _nextId++;
        PtrConnection conn(new Connection(_threadPool.NextLoop(), _nextId, newFd));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        if (_enableInactiveRelease)
            conn->EnableInactiveRelease(_timeout); // 启动非活跃超时销毁
        conn->Established();                       // 就绪初始化
        _conns.insert(std::make_pair(_nextId, conn));
    }

    // 移除连接inloop（防止释放连接时，连接还未到达待关闭状态）
    void RemoveConnectionInLoop(const PtrConnection &conn)
    {
        int id = conn->Id();
        auto it = _conns.find(id);
        if (it != _conns.end())
        {
            _conns.erase(it);
        }
    }

    // 从管理Connection的_conns中移除连接信息
    void RemoveConnection(const PtrConnection &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }

public:
    TcpServer(int port) : _port(port),
                          _nextId(0),
                          _enableInactiveRelease(false),
                          _acceptor(&_baseloop, port),
                          _threadPool(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
        _acceptor.Listen(); // 将监听套接字挂到baseloop上
    }
    void SetThreadCount(int count) { return _threadPool.SetThreadCount(count); }
    void SetConnectedCallback(const ConnectedCallback &cb) { _connected_callback = cb; }
    void SetMessageCallback(const MessageCallback &cb) { _message_callback = cb; }
    void SetClosedCallback(const ClosedCallback &cb) { _closed_callback = cb; }
    void SetAnyEventCallback(const AnyEventCallback &cb) { _event_callback = cb; }
   
   //连接定时销毁
    void EnableInactiveRelease(int timeout)
    {
        _timeout = timeout;
        _enableInactiveRelease = true;
    }

    // 添加一个定时任务
    void RunAfter(const Functor &task, int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
    }

    // 启动服务端（线程池创建 + 打开主线程的epoll监控并开始接收新连接）
    void Start()
    {
        _threadPool.Create();
        _baseloop.Start();
    }

};

//忽略单个连接断开时，发出的SIGPIPE信号关闭整个程序
class NetWork {
    public:
        NetWork() {
            DLOG("SIGPIPE INIT");
            signal(SIGPIPE, SIG_IGN);
        }
};
static NetWork nw;